package com.example.micinter_ipcamera;

import android.content.Context;
import android.graphics.ImageFormat;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.util.Size;

import androidx.annotation.NonNull;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ImageAnalysis;
import androidx.camera.core.ImageProxy;
import androidx.camera.core.Preview;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.camera.view.PreviewView;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.LifecycleOwner;

import com.google.common.util.concurrent.ListenableFuture;

import java.io.ByteArrayOutputStream;
import java.nio.ByteBuffer;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicReference;

public class CameraStreamManager {

    private final Context context;
    private final PreviewView previewView;
    private final LifecycleOwner lifecycleOwner;
    private final AtomicReference<byte[]> latestJpeg;
    private ProcessCameraProvider cameraProvider;
    private ImageAnalysis imageAnalysis;
    private CameraSettings settings;
    private ExecutorService imageProcessingExecutor;

    public CameraStreamManager(Context context, PreviewView previewView, LifecycleOwner lifecycleOwner, AtomicReference<byte[]> latestJpeg) {
        this.context = context.getApplicationContext();
        this.previewView = previewView;
        this.lifecycleOwner = lifecycleOwner;
        this.latestJpeg = latestJpeg;
        this.settings = new CameraSettings();
        // 创建专用的图像处理线程池，使用单线程确保顺序处理
        this.imageProcessingExecutor = Executors.newSingleThreadExecutor();
    }

    public void setSettings(CameraSettings settings) {
        this.settings = settings;
        // 如果相机已经启动，重新绑定以应用新设置
        if (cameraProvider != null) {
            bindUseCases();
        }
    }

    public CameraSettings getSettings() {
        return settings;
    }

    public void switchCamera() {
        if (settings != null) {
            settings.toggleCamera();
            if (cameraProvider != null) {
                bindUseCases();
            }
        }
    }

    public void startCamera() {
        ListenableFuture<ProcessCameraProvider> cameraProviderFuture = ProcessCameraProvider.getInstance(context);
        cameraProviderFuture.addListener(() -> {
            try {
                cameraProvider = cameraProviderFuture.get();
                bindUseCases();
            } catch (ExecutionException | InterruptedException e) {
                // ignore
            }
        }, getExecutor());
    }

    public void stopCamera() {
        if (cameraProvider != null) {
            cameraProvider.unbindAll();
        }
        if (imageProcessingExecutor != null) {
            imageProcessingExecutor.shutdown();
        }
    }

    private void bindUseCases() {
        Preview preview = new Preview.Builder().build();
        preview.setSurfaceProvider(previewView.getSurfaceProvider());

        // 使用设置中的分辨率，默认320x240以提高流畅度
        Size targetResolution = settings != null ? settings.getResolution().getSize() : new Size(320, 240);
        imageAnalysis = new ImageAnalysis.Builder()
                .setTargetResolution(targetResolution)
                .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST) // 只保留最新帧，丢弃旧帧
                .build();

        // 获取当前质量设置，默认50以提高压缩速度
        final int jpegQuality = settings != null ? settings.getQuality().getValue() : 50;
        
        // 使用后台线程处理图像，避免阻塞CameraX
        imageAnalysis.setAnalyzer(imageProcessingExecutor, new ImageAnalysis.Analyzer() {
            @Override
            public void analyze(@NonNull ImageProxy image) {
                // 先读取所有需要的数据，然后再关闭图像
                int width = image.getWidth();
                int height = image.getHeight();
                ImageProxy.PlaneProxy[] planes = image.getPlanes();
                
                // 快速读取YUV数据
                ByteBuffer yBuffer = planes[0].getBuffer();
                ByteBuffer uBuffer = planes[1].getBuffer();
                ByteBuffer vBuffer = planes[2].getBuffer();
                
                int ySize = yBuffer.remaining();
                int uSize = uBuffer.remaining();
                int vSize = vBuffer.remaining();
                
                byte[] yBytes = new byte[ySize];
                byte[] uBytes = new byte[uSize];
                byte[] vBytes = new byte[vSize];
                
                yBuffer.get(yBytes);
                uBuffer.get(uBytes);
                vBuffer.get(vBytes);
                
                // 在关闭图像前读取 stride 信息
                int chromaRowStride = planes[1].getRowStride();
                int chromaPixelStride = planes[1].getPixelStride();
                
                // 立即关闭图像，释放CameraX资源
                image.close();
                
                // 在后台线程中处理YUV到JPEG的转换
                processFrameAsync(yBytes, uBytes, vBytes, width, height, 
                        chromaRowStride, chromaPixelStride, jpegQuality);
            }
        });

        // 根据设置选择摄像头
        CameraSelector cameraSelector = (settings != null && settings.isUseBackCamera()) 
                ? CameraSelector.DEFAULT_BACK_CAMERA 
                : CameraSelector.DEFAULT_FRONT_CAMERA;
        
        cameraProvider.unbindAll();
        cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, preview, imageAnalysis);
    }

    private Executor getExecutor() {
        return ContextCompat.getMainExecutor(context);
    }

    private void processFrameAsync(byte[] yBytes, byte[] uBytes, byte[] vBytes, 
                                   int width, int height, int chromaRowStride, 
                                   int chromaPixelStride, int jpegQuality) {
        // 在后台线程中执行耗时操作
        imageProcessingExecutor.execute(() -> {
            try {
                byte[] nv21 = yuvToNv21(yBytes, uBytes, vBytes, width, height, chromaRowStride, chromaPixelStride);
                if (nv21 != null) {
                    YuvImage yuvImage = new YuvImage(nv21, ImageFormat.NV21, width, height, null);
                    ByteArrayOutputStream jpegOut = new ByteArrayOutputStream();
                    // 使用较低的质量以提高压缩速度
                    yuvImage.compressToJpeg(new Rect(0, 0, width, height), jpegQuality, jpegOut);
                    latestJpeg.set(jpegOut.toByteArray());
                }
            } catch (Exception e) {
                // 忽略处理错误，继续处理下一帧
            }
        });
    }

    private static byte[] yuvToNv21(byte[] yBytes, byte[] uBytes, byte[] vBytes,
                                    int width, int height, int chromaRowStride, int chromaPixelStride) {
        int ySize = yBytes.length;
        int nv21Size = ySize + uBytes.length + vBytes.length;
        byte[] nv21 = new byte[nv21Size];
        
        // 复制Y平面
        System.arraycopy(yBytes, 0, nv21, 0, ySize);
        
        int offset = ySize;
        int uvWidth = width / 2;
        int uvHeight = height / 2;
        
        // 如果数据是连续的，快速复制
        if (chromaPixelStride == 1 && chromaRowStride == uvWidth) {
            int uvSize = Math.min(uBytes.length, vBytes.length);
            for (int i = 0; i < uvSize; i++) {
                nv21[offset++] = vBytes[i];
                nv21[offset++] = uBytes[i];
            }
            return nv21;
        }
        
        // 一般情况：按像素复制
        for (int row = 0; row < uvHeight; row++) {
            for (int col = 0; col < uvWidth; col++) {
                int vuIndex = row * chromaRowStride + col * chromaPixelStride;
                if (vuIndex < vBytes.length && vuIndex < uBytes.length) {
                    nv21[offset++] = vBytes[vuIndex];
                    nv21[offset++] = uBytes[vuIndex];
                }
            }
        }
        return nv21;
    }

}


